package com.novellotus.iov.carvice.activity;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.jaeger.library.StatusBarUtil;
import com.novellotus.iov.carvice.R;
import com.novellotus.iov.carvice.bean.MapCarListBean;
import com.novellotus.iov.carvice.bean.MqttListCarBean;
import com.novellotus.iov.carvice.bean.MqttSingleCarStatue;
import com.novellotus.iov.carvice.bean.MqttVehicleBean;
import com.novellotus.iov.carvice.maps.ClusterClickListener;
import com.novellotus.iov.carvice.maps.ClusterOverlay;
import com.novellotus.iov.carvice.maps.ClusterRender;
import com.novellotus.iov.carvice.maps.SensorEventHelper;
import com.novellotus.iov.carvice.model.MapCarModel;
import com.novellotus.iov.carvice.model.MqttModule;
import com.novellotus.iov.carvice.retrofit.BaseArrayEntity;
import com.novellotus.iov.carvice.retrofit.BaseArrayObserver;
import com.novellotus.iov.carvice.retrofit.RetrofitFactory;
import com.novellotus.iov.carvice.retrofit.RxSchedulers;
import com.novellotus.iov.carvice.utils.MyUtils;
import com.novellotus.iov.carvice.utils.SharedPreferencesUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * 地图上车辆
 */
public class MapCarActivity extends AppCompatActivity implements LocationSource,
        AMapLocationListener, AMap.OnMarkerClickListener, ClusterRender,
        ClusterClickListener, AMap.OnCameraChangeListener, AMap.OnMapLoadedListener, MqttModule.MqttMessageInterface {

    private AMap aMap;
    @BindView(R.id.map)
    MapView mapView;
    @BindView(R.id.tv_tittle)
    TextView tv_tittle;
    @BindView(R.id.hideView)
    View hideView;
    private AMapLocationClient locationClient;
    private AMapLocationClientOption mLocationOption;
    private Marker mLocMarker;
    private OnLocationChangedListener mListener;
    private ClusterOverlay mClusterOverlay;
    private Map<Integer, Drawable> mBackDrawAbles = new HashMap<>();
    private MapCarModel mapCarModel;
    private MqttModule mqttModule;
    private String[] key;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map_car);
        StatusBarUtil.setTransparent(this);
        ButterKnife.bind(this);
        mapView.onCreate(savedInstanceState);
        init();
    }

    /**
     * 实例化
     */
    void init() {
        if (aMap == null) {
            aMap = mapView.getMap();
            setUpMap();
        }
        key = SharedPreferencesUtils.getKey(this);
        mSensorHelper = new SensorEventHelper(this);
        mSensorHelper.registerSensorListener();
        initLocation();
        tv_tittle.setText("地图监控");
        mapCarModel = new MapCarModel(this);
        onMapLoaded();
        setTopic();

    }

    /**
     * 根据关注的车辆订阅mqtt主题
     */
    private void setTopic() {

        String topic[] = new String[]{"$NL/ne/evbus/" + key[2] + "/follow_vehicles"};
        mqttModule = new MqttModule(this, this, key[0], key[1]);
        mqttModule.setTop(topic, 0);
        mqttModule.startReconnect();
    }


    /**
     * 设置一些amap的属性
     */
    private void setUpMap() {
        aMap.setLocationSource(this);// 设置定位监听
        aMap.getUiSettings().setRotateGesturesEnabled(false);
        aMap.getUiSettings().setZoomControlsEnabled(false);
        aMap.getUiSettings().setMyLocationButtonEnabled(false);// 设置默认定位按钮是否显示
        aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        aMap.setOnCameraChangeListener(this);
        aMap.setOnMarkerClickListener(this);
        aMap.setMinZoomLevel(4);
        aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
    }

    /**
     * 初始化定位
     */
    private void initLocation() {
        mLocationOption = new AMapLocationClientOption();
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        mLocationOption.setOnceLocation(true);
        mLocationOption.setOnceLocationLatest(true);
        locationClient = new AMapLocationClient(this.getApplicationContext());
        locationClient.setLocationListener(this);
        locationClient.startLocation();
    }

    /**
     * @param latlng 自定义可以旋转的marker
     */
    private void addMarker(LatLng latlng) {
        if (mLocMarker != null) {
            return;
        }
        MarkerOptions options = new MarkerOptions();
        options.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(this.getResources(),
                R.mipmap.navi_map_gps_locked)));
        options.anchor(0.5f, 0.5f);
        options.position(latlng);
        mLocMarker = aMap.addMarker(options);
        mLocMarker.setClickable(false);
        mLocMarker.setTitle("mylocation");
    }

    @OnClick(R.id.img_back)
    void back() {
        finish();
    }

    @OnClick(R.id.ibt_location)
    void clickLocation() {
        if (location != null) {
            aMap.moveCamera(CameraUpdateFactory.changeLatLng(location));
        }
    }

    LatLng location;
    private boolean mFirstFix = false;
    private SensorEventHelper mSensorHelper;
    private AMapLocation mCurrentLocation;

    @Override
    public void onLocationChanged(AMapLocation amapLocation) {
        if (mListener != null && amapLocation != null) {
            if (amapLocation.getErrorCode() == 0) {
                location = new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude());
                if (!mFirstFix) {
                    mFirstFix = true;
                    addMarker(location);//添加定位图标
                    mSensorHelper.setCurrentMarker(mLocMarker);//定位图标旋转
                    aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 4));
                } else {
                    mLocMarker.setPosition(location);
                    // aMap.moveCamera(CameraUpdateFactory.changeLatLng(location));
                }
                mCurrentLocation = amapLocation;
            } else {
                String errText = "定位失败," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();
                Log.e("AmapErr", errText);
            }
        }
    }

    @Override
    public void activate(OnLocationChangedListener onLocationChangedListener) {
        mListener = onLocationChangedListener;
    }

    @Override
    public void deactivate() {
        mListener = null;
        if (locationClient != null) {
            locationClient.stopLocation();
            locationClient.onDestroy();
        }
        locationClient = null;
    }

    @Override
    public boolean onMarkerClick(Marker marker) {
        return false;
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
        if (mSensorHelper != null) {
            mSensorHelper.registerSensorListener();
        }

    }

    @Override
    protected void onRestart() {
        super.onRestart();
        if (mqttModule != null) {
            mqttModule.startReconnect();
        }
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
        if (mqttModule != null) {
            mqttModule.stopConnect();
        }
        if (mSensorHelper != null) {
            mSensorHelper.unRegisterSensorListener();
            mSensorHelper.setCurrentMarker(null);
            mSensorHelper = null;
        }
        deactivate();
        mFirstFix = false;
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
        if (mClusterOverlay != null) {
            mClusterOverlay.onDestroy();
        }
        if (mLocMarker != null) {
            mLocMarker.destroy();
        }
        if (mqttModule != null) {
            mqttModule.destroyModule();
        }
        mClusterOverlay = null;
        mqttModule = null;
        destroyLocation();
    }

    private void destroyLocation() {
        if (locationClient != null) {
            locationClient.unRegisterLocationListener(this);
            locationClient.onDestroy();
        }
    }

    @Override
    public Drawable getDrawAble(int clusterNum, int statue) {
        mBackDrawAbles.clear();
        int radius = dp2px(getApplicationContext(), 80);
        if (clusterNum == 1) {
            Drawable bitmapDrawable = null;
            switch (statue) {
                case 0:
                    bitmapDrawable = getApplication().getResources().getDrawable(
                            R.mipmap.icon_map_car_outline);
                    break;
                case 1:
                    bitmapDrawable = getApplication().getResources().getDrawable(
                            R.mipmap.icon_map_car_run);
                    break;
                case 2:
                    bitmapDrawable = getApplication().getResources().getDrawable(
                            R.mipmap.icon_map_car_charging);
                    break;
                case 3:
                    bitmapDrawable = getApplication().getResources().getDrawable(
                            R.mipmap.icon_map_car_warn_1);
                    break;
                case 4:
                    bitmapDrawable = getApplication().getResources().getDrawable(
                            R.mipmap.icon_map_car_warn_2);
                    break;
                case 5:
                    bitmapDrawable = getApplication().getResources().getDrawable(
                            R.mipmap.icon_map_car_warn_3);
                    break;
                case 10:
                    bitmapDrawable = getApplication().getResources().getDrawable(
                            R.mipmap.icon_map_car_outline_click);
                    break;
                case 11:
                    bitmapDrawable = getApplication().getResources().getDrawable(
                            R.mipmap.icon_map_car_run_click);
                    break;
                case 12:
                    bitmapDrawable = getApplication().getResources().getDrawable(
                            R.mipmap.icon_map_car_charging_click);
                    break;
                case 13:
                    bitmapDrawable = getApplication().getResources().getDrawable(
                            R.mipmap.icon_map_car_warn_1_click);
                    break;
                case 14:
                    bitmapDrawable = getApplication().getResources().getDrawable(R.mipmap.icon_map_car_warn_2_click);
                    break;
                case 15:
                    bitmapDrawable = getApplication().getResources().getDrawable(
                            R.mipmap.icon_map_car_warn_3_click);
                    break;
            }
            mBackDrawAbles.put(1, bitmapDrawable);
            return bitmapDrawable;
        } else if (clusterNum < 5) {

            Drawable bitmapDrawable = mBackDrawAbles.get(2);
            if (bitmapDrawable == null) {
                bitmapDrawable = new BitmapDrawable(null, drawCircle(radius,
                        Color.parseColor("#7100b3f7")));
                mBackDrawAbles.put(2, bitmapDrawable);
            }
            return bitmapDrawable;
        } else if (clusterNum < 10) {
            Drawable bitmapDrawable = mBackDrawAbles.get(3);
            if (bitmapDrawable == null) {
                bitmapDrawable = new BitmapDrawable(null, drawCircle(radius,
                        Color.parseColor("#7100b3f7")));
                mBackDrawAbles.put(3, bitmapDrawable);
            }
            return bitmapDrawable;
        } else {
            Drawable bitmapDrawable = mBackDrawAbles.get(4);
            if (bitmapDrawable == null) {
                bitmapDrawable = new BitmapDrawable(null, drawCircle(radius,
                        Color.parseColor("#7100b3f7")));
                mBackDrawAbles.put(4, bitmapDrawable);
            }
            return bitmapDrawable;
        }
    }

    @Override
    public void onClick(Marker marker, List<MapCarListBean> clusterItems) {
     //   aMap.moveCamera(CameraUpdateFactory.newLatLng(marker.getPosition()));

        if (clusterItems.size() == 1) {
            show(marker, clusterItems.get(0));
            aMap.moveCamera(CameraUpdateFactory.newLatLng(marker.getPosition()));
        }else{
            aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(marker.getPosition(),25));
        }
    }


    PopupWindow popupWindow;
    int carStatue;
    TextView tv_statue;

    private void show(final Marker marker, final MapCarListBean carListBean) {

        View layout = View.inflate(this, R.layout.layout_map_car_click, null);
        TextView tv_plate = layout.findViewById(R.id.tv_plate);
        TextView tv_vin = layout.findViewById(R.id.tv_vin);
        tv_statue = layout.findViewById(R.id.tv_statue);
        mClusterOverlay.setClickVin(carListBean.getVin());
        if (carListBean.getOnlineStatus() == 1) {
            carStatue = MyUtils.carDetailType(carListBean.getOnlineStatus(), carListBean.getChargeStatus(), carListBean.getAlarmStatus());
            switch (carStatue) {
                case 1:
                    tv_statue.setBackgroundResource(R.drawable.shape_corners_online);
                    tv_statue.setText("运行");
                    marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_map_car_run_click));
                    break;
                case 2:
                    tv_statue.setBackgroundResource(R.drawable.shape_corners_charging);
                    tv_statue.setText("充电中");
                    marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_map_car_charging_click));
                    break;
                case 3:
                    tv_statue.setBackgroundResource(R.drawable.shape_one_alram);
                    tv_statue.setText("一级报警");
                    carStatue = 3;
                    marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_map_car_warn_1_click));
                    break;
                case 4:
                    tv_statue.setBackgroundResource(R.drawable.shape_two_alarm);
                    tv_statue.setText("二级报警");
                    marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_map_car_warn_2_click));
                    break;
                case 5:
                    tv_statue.setBackgroundResource(R.drawable.shape_corners_alarm);
                    tv_statue.setText("三级报警");
                    marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_map_car_warn_3_click));
                    break;
            }
        } else {
            tv_statue.setBackgroundResource(R.drawable.shape_corners_outline);
            tv_statue.setText("离线");
            marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_map_car_outline_click));
        }


        ImageView img_navi = layout.findViewById(R.id.img_navi);
        img_navi.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Bundle bundle = new Bundle();
                bundle.putString("vin", carListBean.getVin());
                bundle.putString("plate", carListBean.getPn());
                bundle.putInt("type", MyUtils.carType(carListBean.getOnlineStatus(), carListBean.getChargeStatus(), carListBean.getAlarmStatus()));
                Intent intent = new Intent(MapCarActivity.this, CarDetailActivity.class);
                intent.putExtras(bundle);
                startActivity(intent);
            }
        });
        tv_plate.setText(carListBean.getPn());
        tv_vin.setText(carListBean.getVin());
        popupWindow = new PopupWindow(layout, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, false);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setBackgroundDrawable(new BitmapDrawable(null, ""));
        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
                                             @Override
                                             public void onDismiss() {
                                                 mClusterOverlay.setClickVin("");
                                                 if (mClusterOverlay != null) {
                                                     mClusterOverlay.onCameraChangeFinish();
                                                 }
//                                                 switch (carStatue) {
//                                                     case 0:
//                                                         MyUtils.logInformation("执行！~！~！");
//                                                         marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_map_car_outline));
//                                                         break;
//                                                     case 1:
//                                                         marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_map_car_run));
//                                                         break;
//                                                     case 2:
//                                                         marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_map_car_charging));
//                                                         break;
//                                                     case 3:
//                                                         marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_map_car_warn_1));
//                                                         break;
//                                                     case 4:
//                                                         marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_map_car_warn_2));
//                                                         break;
//                                                     case 5:
//                                                         marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_map_car_warn_3));
//                                                         break;
//                                                 }
                                             }
                                         }
        );
        popupWindow.showAtLocation(hideView, Gravity.BOTTOM, 0, 0);
    }

    private int clusterRadius = 10;

    /**
     * 然后进行点聚合
     */
    @Override
    public void onMapLoaded() {
        Observable.create(new ObservableOnSubscribe<List<MapCarListBean>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<MapCarListBean>> e) throws Exception {
                RetrofitFactory.getInstance().getAllVehicleData(SharedPreferencesUtils.getKey(MapCarActivity.this)[0])
                        .compose(RxSchedulers.<BaseArrayEntity<MapCarListBean>>compose())
                        .subscribe(new BaseArrayObserver<MapCarListBean>(MapCarActivity.this) {

                            @Override
                            public void onSuccess(List<MapCarListBean> t) {
                                e.onNext(t);
                            }

                            @Override
                            public void onFail(int code, String msg) {
                                MyUtils.showToast(MapCarActivity.this, "加载车辆数据失败");
                            }

                            @Override
                            public void onError(String msg) {
                            }

                        });

            }
        }).observeOn(Schedulers.io())
                .subscribe(new Consumer<List<MapCarListBean>>() {
                    @Override
                    public void accept(List<MapCarListBean> mapCarListBeanList) throws Exception {
                        mClusterOverlay = new ClusterOverlay(aMap, mapCarListBeanList, dp2px(getApplicationContext(), clusterRadius),
                                getApplicationContext());
                        mClusterOverlay.setClusterRenderer(MapCarActivity.this);
                        mClusterOverlay.setOnClusterClickListener(MapCarActivity.this);


                    }
                });
    }

    private Bitmap drawCircle(int radius, int color) {

        Bitmap bitmap = Bitmap.createBitmap(radius * 2, radius * 2,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        RectF rectF = new RectF(0, 0, radius * 2, radius * 2);
        paint.setColor(color);
        canvas.drawArc(rectF, 0, 360, true, paint);
        return bitmap;
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public int dp2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    @Override
    public void onCameraChange(CameraPosition cameraPosition) {
    }

    @Override
    public void onCameraChangeFinish(CameraPosition cameraPosition) {
        // mapCarModel.getCar(aMap, cameraPosition);
        if (mClusterOverlay != null) {
            mClusterOverlay.onCameraChangeFinish();
        }

    }


    @Override
    public void getTopic(MqttListCarBean mqttListCarBean, MqttVehicleBean mqttVehicleBean, String vin) {
        //刷新弹窗信息
        if (popupWindow != null && popupWindow.isShowing() && mqttListCarBean.getVin().equals(mClusterOverlay.getClickVin())) {
            int carType = MyUtils.carType(mqttListCarBean.getOnlineStatus(), mqttListCarBean.getChargeStatus(), mqttListCarBean.getAlarmStatus());

            if (mqttListCarBean.getOnlineStatus() == 0) {
                carStatue = 0;
                tv_statue.setBackgroundResource(R.drawable.shape_corners_outline);
                tv_statue.setText("离线");
            } else {
                carStatue = MyUtils.carDetailType(mqttListCarBean.getOnlineStatus(), mqttListCarBean.getChargeStatus(), mqttListCarBean.getAlarmStatus());
                switch (carStatue) {
                    case 0:
                        tv_statue.setBackgroundResource(R.drawable.shape_corners_outline);
                        tv_statue.setText("离线");
                        break;
                    case 1:
                        tv_statue.setBackgroundResource(R.drawable.shape_corners_online);
                        tv_statue.setText("运行中");
                        break;
                    case 2:
                        tv_statue.setBackgroundResource(R.drawable.shape_corners_charging);
                        tv_statue.setText("充电中");
                        break;
                    case 3:
                        tv_statue.setBackgroundResource(R.drawable.shape_one_alram);
                        tv_statue.setText("一级报警");
                        break;
                    case 4:
                        tv_statue.setBackgroundResource(R.drawable.shape_two_alarm);
                        tv_statue.setText("二级报警");
                        break;
                    case 5:
                        tv_statue.setBackgroundResource(R.drawable.shape_corners_alarm);
                        tv_statue.setText("三级报警");
                        break;
                }
            }

        }
        mClusterOverlay.updateMqttCar(mqttListCarBean, vin);
    }

    @Override
    public void getSingleCarStatue(MqttSingleCarStatue mqttSingleCarStatue) {

    }
}
